import Tkinter
from threading import Thread
import Queue
import time

from ttrModuleLoad import *


class ScrolledText(Tkinter.Frame):
    def __init__(self, parent=None, text='', scrollSide=Tkinter.RIGHT, state=Tkinter.NORMAL, height=10):
        '''Widget with scroll bar. 
        set state=Tkinter.DISABLED for display only
        addText to add text at the end
        setText() to set or clear the whole content
        getText() to get the content
        '''
        self.state = state
        self.scrollSide = scrollSide
        self.height = height
        Tkinter.Frame.__init__(self, parent)
        self.pack(expand=Tkinter.YES, fill=Tkinter.BOTH)                 
        self.makewidgets()
        self.setText(text)

    def makewidgets(self):
        sbar = Tkinter.Scrollbar(self)
        txt = Tkinter.Text(self, relief=Tkinter.SUNKEN, height=self.height)
        sbar.config(command=txt.yview)               
        txt.config(yscrollcommand=sbar.set)
        if self.scrollSide == Tkinter.RIGHT:
            sbar.pack(side=Tkinter.RIGHT, fill=Tkinter.Y)                 
            txt.pack(side=Tkinter.LEFT, expand=Tkinter.YES, fill=Tkinter.BOTH)  
        else:
            sbar.pack(side=Tkinter.LEFT, fill=Tkinter.Y)                 
            txt.pack(side=Tkinter.RIGHT, expand=Tkinter.YES, fill=Tkinter.BOTH)  
        
        self.txt = txt
        self.sbar = sbar

    def setText(self, text=''):
        self.txt.config(state=Tkinter.NORMAL)
        self.txt.delete('1.0', Tkinter.END)                 
        self.txt.insert('1.0', text)               
        #self.txt.mark_set(Tkinter.INSERT, Tkinter.END)          
        self.txt.focus()
        self.txt.config(state=self.state)
        self.txt.yview_moveto(1.0) # last line
        
        
    def addText(self, text):
        self.txt.config(state=Tkinter.NORMAL)
        self.txt.insert(Tkinter.END, text)
        #self.txt.mark_set(Tkinter.INSERT, Tkinter.END)
        self.txt.config(state=self.state)
        self.txt.yview_moveto(1.0) # last line
        
    def getText(self):                             
        return self.txt.get('1.0', Tkinter.END+'-1c') # remove last char
        
 
class msg_table(Tkinter.Frame):
    '''
    setup a scroll text window and a input message window.
    anything type into message window, will be put into the msgQueue 
    to send to server, anything in txtQueue will be displayed in the scrolledTexT window
    the mainloop of parent is used to poll msgQueue and txtQueue
    '''
    def __init__(self, parent=None, msgQueue=None, txtQueue=None):
        self.parent = parent
        self.msgQueue = msgQueue
        self.txtQueue = txtQueue
        Tkinter.Frame.__init__(self, parent)
        self.dispTxt = ScrolledText(parent=parent, text='', scrollSide=Tkinter.LEFT, state=Tkinter.DISABLED)
        self.pack()
        self.txt = Tkinter.Text(self, height=2)
        self.txt.pack(side=Tkinter.TOP, expand=Tkinter.YES, fill=Tkinter.BOTH)
        
        self.txt.bind('<Key-Return>', self.msgOut)
        self.checkTxtQueue()
        
    def msgOut(self, event):
        # output message window content
        msg = self.txt.get('1.0', Tkinter.END+'-1c')
        self.msgQueue.put(msg)
        #self.dispTxt.addText(text=msg) 
        self.txt.delete('1.0', Tkinter.END) #clear msg
        
    def checkTxtQueue(self):
        # polling of txtQueue
        while not self.txtQueue.empty():
            txt = self.txtQueue.get().strip()
            self.dispTxt.addText(text=txt+'\n')
            
        self.parent.after(CLIENT_GUI_TXT_POLL_TIME_MS, self.checkTxtQueue)
        
    def quit(self):
        self.parent.destroy()


def msg_proc(msg_q, txt_q):
    global root
    # the message process thread
    msg = ''
    while msg != 'exit':
        if not msg_q.empty():
            msg = msg_q.get().strip()
            print msg
            txt_q.put(msg)
    root.quit()
    #time.sleep(1)
    #root.destroy()
    print 'out'
    
        
def main():
    global root
    
    def shutdown():
        # self.track is a variable in class SoundPanel and 
        # needs to be associated with the proper instance
        root.destroy()
    
    
    msg_q = Queue.Queue() #from user input
    txt_q = Queue.Queue() #to be displayed
    
    t = Thread(target=msg_proc, args=(msg_q, txt_q,))
    t.setDaemon(True)
    t.start()

    root = Tkinter.Tk()
    msg_tab = msg_table(root, msg_q, txt_q)
    
        
    # shut it down orderly
    root.protocol("WM_DELETE_WINDOW", shutdown)
    # run the event loop
    root.mainloop()
    
    
    
        
if __name__ == '__main__':
    main()